home *** CD-ROM | disk | FTP | other *** search
/ Visual Cafe 3 / Visual Cafe 3.ISO / Vcafe / JFC.bin / UIManager.java < prev    next >
Text File  |  1998-06-30  |  23KB  |  677 lines

  1. /*
  2.  * @(#)UIManager.java    1.58 98/04/06
  3.  * 
  4.  * Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
  5.  * 
  6.  * This software is the confidential and proprietary information of Sun
  7.  * Microsystems, Inc. ("Confidential Information").  You shall not disclose
  8.  * such Confidential Information and shall use it only in accordance with the
  9.  * terms of the license agreement you entered into with Sun.
  10.  * 
  11.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
  12.  * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  13.  * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
  14.  * OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY
  15.  * LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR
  16.  * ITS DERIVATIVES.
  17.  * 
  18.  */
  19. package com.sun.java.swing;
  20.  
  21. import java.awt.Container;
  22. import java.awt.Window;
  23. import java.awt.Font;
  24. import java.awt.Color;
  25.  
  26. import com.sun.java.swing.plaf.ComponentUI;
  27. import com.sun.java.swing.border.Border;
  28.  
  29. import java.beans.PropertyChangeSupport;
  30. import java.beans.PropertyChangeListener;
  31. import java.beans.PropertyChangeEvent;
  32.  
  33. import java.io.FileOutputStream;
  34. import java.io.IOException;
  35. import java.io.ObjectOutputStream;
  36. import java.io.ObjectInputStream;
  37. import java.io.Serializable;
  38. import java.io.File;
  39. import java.io.FileInputStream;
  40. import java.io.BufferedInputStream;
  41.  
  42. import java.util.Enumeration;
  43. import java.util.Hashtable;
  44. import java.util.Properties;
  45. import java.util.StringTokenizer;
  46. import java.util.Vector;
  47.  
  48.  
  49. /**
  50.  * This class keeps track of the current look and feel and its
  51.  * defaults.
  52.  * <p>
  53.  * We manage three levels of defaults: user defaults, look
  54.  * and feel defaults, system defaults.  A call to UIManager.get()
  55.  * checks all three levels in order and returns the first non-null 
  56.  * value for a key, if any.  A call to UIManager.put() just
  57.  * affects the user defaults.  Note that a call to 
  58.  * setLookAndFeel() doesn't affect the user defaults, it just
  59.  * replaces the middle defaults "level".
  60.  * <p>
  61.  * Warning: serialized objects of this class will not be compatible with
  62.  * future swing releases.  The current serialization support is appropriate 
  63.  * for short term storage or RMI between Swing1.0 applications.  It will
  64.  * not be possible to load serialized Swing1.0 objects with future releases
  65.  * of Swing.  The JDK1.2 release of Swing will be the compatibility
  66.  * baseline for the serialized form of Swing objects.
  67.  *
  68.  * @version 1.58 04/06/98
  69.  * @author Thomas Ball
  70.  * @author Hans Muller
  71.  */
  72. public class UIManager implements Serializable 
  73. {
  74.     /**
  75.      * This class defines the state managed by the UIManager.  For 
  76.      * Swing applications the fields in this class could just as well
  77.      * be static members of UIManager however we give them "AppContext"
  78.      * scope instead so that applets (and potentially multiple lightweight
  79.      * applications running in a single VM) have their own state. For 
  80.      * example an applet can it's look and feel, see setLookAndFeel().
  81.      * Doing so has no affect on other applets (or the browser).
  82.      */
  83.     private static class LAFState 
  84.     {
  85.         private UIDefaults[] tables = new UIDefaults[2];
  86.  
  87.         boolean initialized = false;
  88.         MultiUIDefaults multiUIDefaults = new MultiUIDefaults(tables);
  89.         LookAndFeel lookAndFeel;
  90.         LookAndFeel multiLookAndFeel = null;
  91.         Vector auxLookAndFeels = null;
  92.         PropertyChangeSupport changeSupport = new PropertyChangeSupport(UIManager.class);
  93.  
  94.         UIDefaults getLookAndFeelDefaults() { return tables[0]; }
  95.         void setLookAndFeelDefaults(UIDefaults x) { tables[0] = x; }
  96.  
  97.         UIDefaults getSystemDefaults() { return tables[1]; }
  98.         void setSystemDefaults(UIDefaults x) { tables[1] = x; }
  99.     }
  100.  
  101.  
  102.     /**
  103.      * The AppContext key for our one LAFState instance.
  104.      */
  105.     private static final Object lafStateACKey = new StringBuffer("LookAndFeel State");
  106.  
  107.  
  108.     /**
  109.      * Return the LAFState object, lazily create one if neccessary.  All access
  110.      * to the LAFState fields is done via this method, e.g.:
  111.      * <pre>
  112.      *     getLAFState().initialized = true;
  113.      * </pre>
  114.      */
  115.     private static LAFState getLAFState() {
  116.         LAFState rv = (LAFState)SwingUtilities.appContextGet(lafStateACKey);
  117.         if (rv != null) {
  118.             return rv;
  119.         }
  120.         synchronized(UIManager.class) {
  121.             rv = (LAFState)SwingUtilities.appContextGet(lafStateACKey);
  122.             if (rv != null) {
  123.                 return rv;
  124.             }
  125.             SwingUtilities.appContextPut(lafStateACKey, (rv = new LAFState()));
  126.             return rv;
  127.         }
  128.     }
  129.  
  130.  
  131.     /* Keys used for the properties file in <java.home>/lib/swing.properties.
  132.      * See loadUserProperties(), initialize().
  133.      */
  134.  
  135.     private static final String defaultLAFKey = "swing.defaultlaf";
  136.     private static final String auxiliaryLAFsKey = "swing.auxiliarylaf";
  137.     private static final String multiplexingLAFKey = "swing.plaf.multiplexinglaf";
  138.     private static final String installedLAFsKey = "swing.installedlafs";
  139.  
  140.     /**
  141.      * Return a swing.properties file key for the attribute of specified 
  142.      * look and feel.  The attr is either "name" or "class", a typical
  143.      * key would be: "swing.installedlaf.windows.name"
  144.      */
  145.     private static String makeInstalledLAFKey(String laf, String attr) {
  146.         return "swing.installedlaf." + laf + "." + attr;
  147.     }
  148.  
  149.     /**
  150.      * The filename for swing.properties is a path like this (Unix version):
  151.      * <java.home>/lib/swing.properties.  This method returns a bogus
  152.      * filename if java.home isn't defined.  
  153.      */
  154.     private static String makeSwingPropertiesFilename() {
  155.         String sep = File.separator;
  156.         String homeDir;
  157.  
  158.         try {
  159.             SwingUtilities.beginPrivileged();
  160.             homeDir = System.getProperty("java.home", "<java.home undefined>");
  161.     } finally {
  162.         SwingUtilities.endPrivileged();
  163.     }
  164.  
  165.         return homeDir + sep + "lib" + sep + "swing.properties";
  166.     }
  167.  
  168.  
  169.     /** 
  170.      * Provide a little information about an installed LookAndFeel
  171.      * for the sake of configuring a menu or for initial application 
  172.      * set up.
  173.      * 
  174.      * @see UIManager#getInstalledLookAndFeels
  175.      * @see LookAndFeel
  176.      */
  177.     public static class LookAndFeelInfo {
  178.         private String name;
  179.         private String className;
  180.  
  181.         public LookAndFeelInfo(String name, String className) {
  182.             this.name = name;
  183.             this.className = className;
  184.         }
  185.  
  186.         /**
  187.          * @return a name suitable for a menu or other presentation
  188.          * @see LookAndFeel#getName
  189.          */
  190.         public String getName() {
  191.             return name;
  192.         }
  193.  
  194.         /**
  195.          * @return the name of the class that implements this LookAndFeel.
  196.          * @see LookAndFeel
  197.          */
  198.         public String getClassName() {
  199.             return className;
  200.         }
  201.  
  202.         public String toString() {
  203.             return getClass().getName() + "[" + getName() + " " + getClassName() + "]";
  204.         }
  205.     }
  206.  
  207.  
  208.     /**
  209.      * The default value of installedLAFS is used when no swing.properties
  210.      * file is available or if the file doesn't contain a "swing.installedlafs"
  211.      * property.   
  212.      * 
  213.      * @see #initializeInstalledLAFs
  214.      */
  215.     private static LookAndFeelInfo[] installedLAFs = {
  216.         new LookAndFeelInfo("Metal", "com.sun.java.swing.plaf.metal.MetalLookAndFeel"),
  217.         new LookAndFeelInfo("CDE/Motif", "com.sun.java.swing.plaf.motif.MotifLookAndFeel"),
  218.         new LookAndFeelInfo("Windows", "com.sun.java.swing.plaf.windows.WindowsLookAndFeel")
  219.     };
  220.  
  221.  
  222.     /** 
  223.      * Return an array of objects that provide some information about the
  224.      * LookAndFeel implementations that have been installed with this 
  225.      * java development kit.  The LookAndFeel info objects can be used
  226.      * by an application to construct a menu of look and feel options for 
  227.      * the user or to set the look and feel at start up time.  Note that 
  228.      * we do not return the LookAndFeel classes themselves here to avoid the
  229.      * cost of unnecessarily loading them.
  230.      * <p>
  231.      * Given a LookAndFeelInfo object one can set the current look and feel
  232.      * like this:
  233.      * <pre>
  234.      * UIManager.setLookAndFeel(info.getClassName());
  235.      * </pre>
  236.      * 
  237.      * @see #setLookAndFeel
  238.      */
  239.     public static LookAndFeelInfo[] getInstalledLookAndFeels() {
  240.         maybeInitialize();
  241.         LookAndFeelInfo[] ilafs = installedLAFs;
  242.         LookAndFeelInfo[] rv = new LookAndFeelInfo[ilafs.length];
  243.         System.arraycopy(ilafs, 0, rv, 0, ilafs.length);
  244.         return rv;
  245.     }
  246.  
  247.  
  248.     /**
  249.      * Replaces the current array of installed LookAndFeelInfos.
  250.      * 
  251.      * @see #getInstalledLookAndFeels
  252.      */
  253.     public static void setInstalledLookAndFeels(LookAndFeelInfo[] infos)
  254.         throws SecurityException
  255.     {
  256.         LookAndFeelInfo[] newInfos = new LookAndFeelInfo[infos.length];
  257.         System.arraycopy(infos, 0, newInfos, 0, infos.length);
  258.         installedLAFs = newInfos;
  259.     }
  260.  
  261.  
  262.     /**
  263.      * Adds the specified look and feel to the current array and
  264.      * then calls setInstalledLookAndFeels.
  265.      * 
  266.      * @see #setInstalledLookAndFeels
  267.      */
  268.     public static void installLookAndFeel(LookAndFeelInfo info) {
  269.         LookAndFeelInfo[] infos = getInstalledLookAndFeels();
  270.         LookAndFeelInfo[] newInfos = new LookAndFeelInfo[infos.length + 1];
  271.         System.arraycopy(infos, 0, newInfos, 0, infos.length);
  272.         newInfos[infos.length] = info;
  273.         setInstalledLookAndFeels(newInfos);
  274.     }
  275.  
  276.  
  277.     public static void installLookAndFeel(String name, String className) {
  278.         installLookAndFeel(new LookAndFeelInfo(name, className));
  279.     }
  280.  
  281.  
  282.     /**
  283.      * Returns The current default look and feel, or null.
  284.      *
  285.      * @return The current default look and feel, or null.
  286.      * @see #setLookAndFeel
  287.      */
  288.     public static LookAndFeel getLookAndFeel() {
  289.         maybeInitialize();
  290.         return getLAFState().lookAndFeel;
  291.     }
  292.     
  293.  
  294.     /**
  295.      * Set the current default look and feel.  
  296.      * <p>
  297.      * This is a JavaBeans bound property.
  298.      * 
  299.      * @exception UnsupportedLookAndFeelException If <code>lnf.isSupportedLookAndFeel()</code> is false.
  300.      * @see #getLookAndFeel
  301.      */
  302.     public static void setLookAndFeel(LookAndFeel newLookAndFeel) 
  303.         throws UnsupportedLookAndFeelException 
  304.     {
  305.         if ((newLookAndFeel != null) && !newLookAndFeel.isSupportedLookAndFeel()) {
  306.             String s = newLookAndFeel.toString() + " not supported on this platform";
  307.             throw new UnsupportedLookAndFeelException(s);
  308.         }
  309.  
  310.         LookAndFeel oldLookAndFeel = getLAFState().lookAndFeel;
  311.         if (oldLookAndFeel != null) {
  312.             oldLookAndFeel.uninitialize();
  313.         }
  314.  
  315.         getLAFState().lookAndFeel = newLookAndFeel;
  316.         if (newLookAndFeel != null) {
  317.             newLookAndFeel.initialize();
  318.             getLAFState().setLookAndFeelDefaults(newLookAndFeel.getDefaults());
  319.         }
  320.         else {
  321.             getLAFState().setLookAndFeelDefaults(null);
  322.         }
  323.  
  324.         getLAFState().changeSupport.firePropertyChange("lookAndFeel", oldLookAndFeel, newLookAndFeel);
  325.     }
  326.  
  327.     
  328.     /**
  329.      * @exception ClassNotFoundException If the LookAndFeel class could not be found.
  330.      * @exception InstantiationException If a new instance of the class couldn't be creatd.
  331.      * @exception IllegalAccessException If the class or initializer isn't accessible. 
  332.      * @exception UnsupportedLookAndFeelException If <code>lnf.isSupportedLookAndFeel()</code> is false.
  333.      */
  334.     public static void setLookAndFeel(String className) 
  335.         throws ClassNotFoundException, 
  336.                InstantiationException, 
  337.                IllegalAccessException,
  338.                UnsupportedLookAndFeelException 
  339.     {
  340.             Class lnfClass = Class.forName(className);
  341.             setLookAndFeel((LookAndFeel)(lnfClass.newInstance()));
  342.     }
  343.  
  344.  
  345.     /**
  346.      * Returns the name of the LookAndFeel class that implements
  347.      * the native systems look and feel if there is one,
  348.      * otherwise the name of the default cross platform LookAndFeel
  349.      * class.
  350.      * 
  351.      * @see #setLookAndFeel()
  352.      * @see #getCrossPlatformLookAndFeelClassName
  353.      */
  354.     public static String getSystemLookAndFeelClassName() {
  355.         String osName;
  356.  
  357.     try {
  358.         SwingUtilities.beginPrivileged();
  359.             osName = System.getProperty("os.name");
  360.     } finally {
  361.         SwingUtilities.endPrivileged();
  362.     }
  363.  
  364.         if (osName != null) {
  365.             if (osName.indexOf("Windows") != -1) {
  366.                 return "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
  367.             }
  368.             else if (osName.indexOf("Solaris") != -1) {
  369.                 return "com.sun.java.swing.plaf.motif.MotifLookAndFeel";
  370.             }
  371.         }
  372.         return getCrossPlatformLookAndFeelClassName();
  373.     }
  374.  
  375.  
  376.     /**
  377.      * Returns the name of the LookAndFeel class that implements
  378.      * the default cross platform look and feel, i.e. the "Java
  379.      * Look and Feel", or JLF.
  380.      * 
  381.      * @return  a string with the JLF implementation-class
  382.      * @see #setLookAndFeel()
  383.      * @see #getSystemLookAndFeelClassName
  384.      */
  385.     public static String getCrossPlatformLookAndFeelClassName() {
  386.         return "com.sun.java.swing.plaf.metal.MetalLookAndFeel";
  387.     }
  388.  
  389.  
  390.     public static UIDefaults getDefaults() {
  391.         maybeInitialize();
  392.         return getLAFState().multiUIDefaults;
  393.     }
  394.     
  395.     public static Font getFont(Object key) { 
  396.         return getDefaults().getFont(key); 
  397.     }
  398.  
  399.     public static Color getColor(Object key) { 
  400.         return getDefaults().getColor(key); 
  401.     }
  402.  
  403.     public static Icon getIcon(Object key) { 
  404.         return getDefaults().getIcon(key); 
  405.     }
  406.  
  407.     public static Border getBorder(Object key) { 
  408.         return getDefaults().getBorder(key); 
  409.     }
  410.  
  411.     public static String getString(Object key) { 
  412.         return getDefaults().getString(key); 
  413.     }
  414.  
  415.     public static Object get(Object key) { 
  416.         return getDefaults().get(key); 
  417.     }
  418.  
  419.     public static Object put(Object key, Object value) { 
  420.         return getDefaults().put(key, value); 
  421.     }
  422.  
  423.     public static ComponentUI getUI(JComponent target) {
  424.         maybeInitialize();
  425.         ComponentUI ui = null;
  426.         LookAndFeel multiLAF = getLAFState().multiLookAndFeel;
  427.         if (multiLAF != null) {
  428.             // This can return null if the multiplexing look and feel
  429.             // doesn't support a particular UI.
  430.             ui = multiLAF.getDefaults().getUI(target);
  431.         }
  432.         if (ui == null) {
  433.             ui = getDefaults().getUI(target);
  434.         }
  435.         return ui;
  436.     }
  437.  
  438.  
  439.     public static UIDefaults getLookAndFeelDefaults() {
  440.         maybeInitialize();
  441.         return getLAFState().getLookAndFeelDefaults();
  442.     }
  443.  
  444.  
  445.     /**
  446.      * Return the list of auxiliary look and feels (can be null).  The
  447.      * auxiliary look and feels tell the multiplexing look and feel what
  448.      * other LookAndFeel classes for a component instance are to be used 
  449.      * in addition to the default LookAndFeel class when creating a 
  450.      * multiplexing UI.  
  451.      * <p>Note these are not the same as the installed look and feels.
  452.      * @see #getInstalledLookAndFeels
  453.      */
  454.     static public LookAndFeel[] getAuxiliaryLookAndFeels() 
  455.     {
  456.         maybeInitialize();
  457.  
  458.         Vector v = getLAFState().auxLookAndFeels;
  459.         if ((v == null) || (v.size() == 0)) {
  460.             return null;
  461.         } 
  462.         else {
  463.             LookAndFeel[] rv = new LookAndFeel[v.size()];
  464.             for (int i = 0; i < rv.length; i++) {
  465.                 rv[i] = (LookAndFeel)v.elementAt(i);
  466.             }
  467.             return rv;
  468.         }
  469.     }
  470.  
  471.  
  472.     /**
  473.      * Add a PropertyChangeListener to the listener list.
  474.      * The listener is registered for all properties.
  475.      *
  476.      * @param listener  The PropertyChangeListener to be added
  477.      * @see java.beans.PropertyChangeSupport
  478.      */
  479.     public synchronized static void addPropertyChangeListener(PropertyChangeListener listener) 
  480.     {
  481.         getLAFState().changeSupport.addPropertyChangeListener(listener);
  482.     }
  483.  
  484.  
  485.     /**
  486.      * Remove a PropertyChangeListener from the listener list.
  487.      * This removes a PropertyChangeListener that was registered
  488.      * for all properties.
  489.      *
  490.      * @param listener  The PropertyChangeListener to be removed
  491.      * @see java.beans.PropertyChangeSupport
  492.      */
  493.     public synchronized static void removePropertyChangeListener(PropertyChangeListener listener) 
  494.     {
  495.         getLAFState().changeSupport.removePropertyChangeListener(listener);
  496.     }
  497.  
  498.  
  499.     private static Properties loadSwingProperties()
  500.     {
  501.         Properties properties = new Properties();
  502.  
  503.         if (UIManager.class.getClassLoader() == null) {
  504.             String sep = File.separator;
  505.             try {
  506.                 SwingUtilities.beginPrivileged();
  507.                 File propertiesFile = new File(makeSwingPropertiesFilename());
  508.                 BufferedInputStream ins = new BufferedInputStream(
  509.                     new FileInputStream(propertiesFile));
  510.                 properties.load(ins);
  511.                 ins.close();
  512.             } catch (Exception e) {
  513.                 properties.clear();
  514.             } finally {
  515.                 SwingUtilities.endPrivileged();
  516.             }
  517.         }
  518.  
  519.         return properties;
  520.     }
  521.  
  522.  
  523.     /**
  524.      * If a swing.properties file exist and it has a swing.installedlafs property
  525.      * then initialize the installedLAFs field.
  526.      * 
  527.      * @see #getInstalledLookAndFeels
  528.      */
  529.     private static void initializeInstalledLAFs(Properties swingProps) 
  530.     {
  531.         String ilafsString = swingProps.getProperty(installedLAFsKey);
  532.         if (ilafsString == null) {
  533.             return;
  534.         }
  535.  
  536.         /* Create a vector that contains the value of the swing.installedlafs
  537.          * property.  For example given "swing.installedlafs=motif,windows"
  538.          * lafs = {"motif", "windows"}.
  539.          */
  540.         Vector lafs = new Vector();
  541.         StringTokenizer st = new StringTokenizer(ilafsString, ",", false);
  542.         while (st.hasMoreTokens()) {
  543.             lafs.addElement(st.nextToken());
  544.         }
  545.  
  546.         /* Look up the name and class for each name in the "swing.installedlafs"
  547.          * list.  If they both exist then add a LookAndFeelInfo to 
  548.          * the installedLafs array.
  549.          */
  550.         Vector ilafs = new Vector(lafs.size());
  551.         for(int i = 0; i < lafs.size(); i++) {
  552.             String laf = (String)lafs.elementAt(i);
  553.             String name = swingProps.getProperty(makeInstalledLAFKey(laf, "name"), laf);
  554.             String cls = swingProps.getProperty(makeInstalledLAFKey(laf, "class"));
  555.             if (cls != null) {
  556.                 ilafs.addElement(new LookAndFeelInfo(name, cls));
  557.             }
  558.         }
  559.  
  560.         installedLAFs = new LookAndFeelInfo[ilafs.size()];
  561.         for(int i = 0; i < ilafs.size(); i++) {
  562.             installedLAFs[i] = (LookAndFeelInfo)(ilafs.elementAt(i));
  563.         }
  564.     }
  565.  
  566.  
  567.     /**
  568.      * If the user has specified a default look and feel, use that.  
  569.      * Otherwise use the look and feel that's native to this platform.
  570.      * If this code is called after the application has expclicitly
  571.      * set it's look and feel, do nothing.
  572.      *
  573.      * @see #maybeInitialize
  574.      */
  575.     private static void initializeDefaultLAF(Properties swingProps)
  576.     {
  577.         if (getLAFState().lookAndFeel != null) {
  578.             return;
  579.         }
  580.  
  581.         String metalLnf = getCrossPlatformLookAndFeelClassName();
  582.         String lnfDefault = metalLnf;
  583.  
  584.         String lnfName = "<undefined>" ;
  585.         try {
  586.             lnfName = swingProps.getProperty(defaultLAFKey, lnfDefault);
  587.             setLookAndFeel(lnfName);
  588.         } catch (Exception e) {
  589.             try {
  590.                 lnfName = swingProps.getProperty(defaultLAFKey, metalLnf);
  591.                 setLookAndFeel(lnfName);
  592.             } catch (Exception e2) {
  593.                 throw new Error("can't load " + lnfName);
  594.             }
  595.         }
  596.     }
  597.  
  598.  
  599.     private static void initializeAuxiliaryLAFs(Properties swingProps)
  600.     {
  601.         String auxLookAndFeelNames = swingProps.getProperty(auxiliaryLAFsKey);
  602.         if (auxLookAndFeelNames == null) {
  603.             return;
  604.         }
  605.  
  606.         Vector auxLookAndFeels = new Vector();
  607.  
  608.         StringTokenizer p = new StringTokenizer(auxLookAndFeelNames,",");
  609.         String factoryName;
  610.  
  611.         /* Try to load each LookAndFeel subclass in the list.
  612.          */
  613.  
  614.         while (p.hasMoreTokens()) {
  615.             String className = p.nextToken();
  616.             try {
  617.                 Class lnfClass = Class.forName(className);
  618.                 auxLookAndFeels.addElement(lnfClass.newInstance());
  619.             } 
  620.             catch (Exception e) {
  621.                 System.err.println("UIManager: failed loading auxiliary look and feel " + className);
  622.             }
  623.         }
  624.  
  625.         /* If there were problems and no auxiliary look and feels were 
  626.          * loaded, make sure we reset auxLookAndFeels to null.
  627.          * Otherwise, we are going to use the MultiLookAndFeel to get
  628.          * all component UI's, so we need to load it now.
  629.          */
  630.  
  631.         if (auxLookAndFeels.size() == 0) {
  632.             auxLookAndFeels = null;
  633.         } 
  634.         else {
  635.             String defaultName = "com.sun.java.swing.plaf.multi.MultiLookAndFeel";
  636.             String className = swingProps.getProperty(multiplexingLAFKey, defaultName);
  637.             try {
  638.                 Class lnfClass = Class.forName(className);
  639.                 getLAFState().multiLookAndFeel = (LookAndFeel)lnfClass.newInstance();
  640.             } 
  641.             catch (Exception exc) {
  642.                 System.err.println("UIManager: failed loading " + className);
  643.                 auxLookAndFeels = null;
  644.             }
  645.         }
  646.  
  647.         getLAFState().auxLookAndFeels = auxLookAndFeels;
  648.     }
  649.  
  650.  
  651.     private static void initializeSystemDefaults(Properties swingProps)
  652.     {
  653.         Object defaults[] = {
  654.             "FocusManagerClassName", "com.sun.java.swing.DefaultFocusManager"
  655.         };
  656.         getLAFState().setSystemDefaults(new UIDefaults(defaults));
  657.     }
  658.  
  659.  
  660.     private static void initialize()
  661.     {
  662.         Properties swingProps = loadSwingProperties();
  663.         initializeSystemDefaults(swingProps);
  664.         initializeDefaultLAF(swingProps);
  665.         initializeAuxiliaryLAFs(swingProps);
  666.         initializeInstalledLAFs(swingProps);
  667.     }
  668.  
  669.  
  670.     synchronized private static void maybeInitialize() {
  671.         if (!getLAFState().initialized) {
  672.             initialize();
  673.             getLAFState().initialized = true;
  674.         }
  675.     }
  676. }
  677.